#include "AsyncOpTracker.h"
using namespace WONAPI;

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
AsyncOp* AsyncOpTracker::Track(AsyncOp *theOp, DWORD theId)
{
	AutoCrit aCrit(mDataCrit);
	mOpMap.insert(theId, theOp);
	return theOp;
}

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
bool AsyncOpTracker::Untrack(AsyncOp *theOp)
{
	AutoCrit aCrit(mDataCrit);
	return mOpMap.erase_val(theOp);
}

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
void AsyncOpTracker::Kill(AsyncOp *theOp)
{
	AutoCrit aCrit(mDataCrit);
	AsyncOpPtr anOp = theOp;
	if(Untrack(theOp))
		anOp->Kill();
}
	
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
void AsyncOpTracker::Kill(DWORD theId)
{
	AutoCrit aCrit(mDataCrit);
	OpMap::iterator anItr = mOpMap.find(theId);
	while(anItr!=mOpMap.end() && anItr->first==theId)
	{
		AsyncOpPtr anOp = anItr->second->val;
		mOpMap.erase(anItr++);
		anOp->Kill();
	}
}

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
void AsyncOpTracker::KillAll()
{
	AutoCrit aCrit(mDataCrit);
	OpMap::iterator anItr = mOpMap.begin();
	while(anItr!=mOpMap.end())
	{
		AsyncOpPtr anOp = anItr->second->val;
		mOpMap.erase(anItr++);
		anOp->Kill();
	}
}

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
void AsyncOpWithTracker::Callback(AsyncOp *theOp, int theParam)
{
	if(!Pending())
		return;

	if(!mOpTracker.Untrack(theOp))
		return;

	CallbackHook(theOp,theParam);
}

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
AsyncOp* AsyncOpWithTracker::Track(AsyncOp *theOp, int theId)
{
	theOp->SetCompletion(new TrackerCompletion(this,theId));
	return mOpTracker.Track(theOp,theId);
}

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
void AsyncOpWithTracker::CleanupHook()
{
	mOpTracker.KillAll();
}

